﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
using System.Linq;

namespace Controllers
{
    public class CardController : BaseController
    {
        class empTemp
        {
            public int Id { get; set; }
            public string JobNo { get; set; }
            public string Name { get; set; }
        }
        class cardLogTemp
        {
            public string JobNo { get; set; }
            public string CardTime { get; set; }
            public string Ip { get; set; }
        }
        public string Find(string idStr, DateTime startDate, DateTime endDate)
        {
            StringBuilder fSb = new StringBuilder();
            fSb.Append("<table class='s1 bordertable'><thead><tr><th width=60>姓名</th>");
            DateTime t = startDate;
            while (t <= endDate)
            {
                fSb.AppendFormat("<th>{0}</th>", t.ToString("MM.dd"));
                t = t.AddDays(1);
            }
            fSb.Append("</tr></thead>");
            
            int empId=0;
            IList<int> deptIdList=null;
            if (idStr.IndexOf("EmpId")>=0)
            {
                empId = int.Parse(idStr.Replace("EmpId", ""));
            }
            else
            {
                deptIdList = getAuthedDeptIds("Card", idStr, out empId);
            }

            IEnumerable<empTemp> ets;
            IEnumerable<cardLogTemp> cls;
            if (empId != 0)
            {
                //按人员Id
                ets = ctx.ExecuteQuery<empTemp>("select Id,JobNo,Name from Employee where Id={0}", empId.ToString());
                cls = ctx.ExecuteQuery<cardLogTemp>(@"select JobNo,CONVERT(varchar,CardTime,120) CardTime,Ip from CardLog where JobNo in(select JobNo from Employee
where Id={0}) and datediff(d,CardTime,{1})<=0 and datediff(d,CardTime,{2})>=0 order by CardTime", empId.ToString(), startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"));
            }
            else
            {
                //按权限部门
                string deptIdsStr = "";
                foreach (int id in deptIdList)
                {
                    deptIdsStr += "," + id;
                }
                string etsStr = string.Format("select b.Id,JobNo,Name from EmpDepPositions a join Employee b on DeptId in({0}) and LeaveDate is null and a.EmpId=b.Id and a.PosId>4", deptIdsStr.Trim(','));
                string clsStr = string.Format(@"select JobNo,CONVERT(varchar,CardTime,120) CardTime from CardLog where JobNo in(select JobNo from EmpDepPositions a join Employee b
on DeptId in({0}) and LeaveDate is null and a.EmpId=b.Id and a.PosId>4) and datediff(d,CardTime,'{1}')<=0 and datediff(d,CardTime,'{2}')>=0 order by CardTime", deptIdsStr.Trim(','), startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"));
                ets = ctx.ExecuteQuery<empTemp>(etsStr);
                cls = ctx.ExecuteQuery<cardLogTemp>(clsStr);
            }
            IList<cardLogTemp> list = cls.ToList();
            foreach (empTemp et in ets)//每人
            {
                DateTime sDate = startDate;
                DateTime eDate = endDate;
                StringBuilder aSb = new StringBuilder();
                aSb.AppendFormat("<tr><td>{0}</td>", et.Name);
                StringBuilder pSb = new StringBuilder();
                pSb.AppendFormat("<tr><td>{0}</td>", et.Name);
                while (sDate <= eDate)//每天
                {
                    //按工号获取打卡记录
                    IEnumerable<cardLogTemp> clst = list.Where(r => r.JobNo == et.JobNo && r.CardTime.Substring(0, 10) == sDate.ToString("yyyy-MM-dd"));
                    if (clst.Count() > 0)//
                    {
                        string aTime = clst.First().CardTime.Substring(11, 5);
                        #region 上班时间大于8:30
                        if (int.Parse(aTime.Replace(":", "")) > 830)
                        {
                            //读取当天的请假记录
                            string vacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 08:30:00"),"");
                            //读取当天的出差记录
                            string evection = GetEvection(et.Name, sDate);
                            if (vacation == "" && evection == "")
                            {
                                if (int.Parse(aTime.Replace(":", "")) <= 900)
                                {
                                    aTime = "<font color='cc0000'>" + aTime + "</font>";
                                }
                                else
                                {
                                    aTime = "<font color='cc0000'>上午旷工</font>";
                                }
                            }
                            else if (vacation != "")
                                aTime = vacation;
                            else if (evection != "")
                                aTime = evection;
                        }
                        #endregion

                        if (!string.IsNullOrEmpty(clst.First().Ip))
                        {
                            aTime += "<br /><span style='font-size:6pt;'>" + clst.First().Ip + "</span>";
                        }
                        string pTime = clst.Last().CardTime.Substring(11, 5);

                        #region //下班时间早于17:30
                        if (int.Parse(pTime.Replace(":", "")) < 1730)
                        {
                            //读取当天的请假记录
                            string vacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 17:30:00"),"");
                            //读取当天的出差记录
                            string evection = GetEvection(et.Name, sDate);
                            if (vacation == "" && evection == "")
                            {
                                if (int.Parse(pTime.Replace(":", "")) >= 1700)
                                {
                                    pTime = "<font color='cc0000'>" + pTime + "</font>";
                                }
                                else
                                {
                                    pTime = "<font color='cc0000'>下午旷工</font>";
                                }
                            }
                            else if (vacation != "")
                                pTime = vacation;
                            else if (evection != "")
                                pTime = evection;
                        }
                        #endregion

                        if (!string.IsNullOrEmpty(clst.Last().Ip))
                        {
                            pTime += "<br /><span style='font-size:6pt;'>" + clst.Last().Ip + "</span>";
                        }
                        aSb.AppendFormat("<td>{0}</td>", aTime);
                        pSb.AppendFormat("<td>{0}</td>", pTime);
                    }
                    else//当天没有打卡记录
                    {
                        //如果是周六日,或者是该日期设置为正常上班
                        if (sDate.DayOfWeek == DayOfWeek.Sunday || sDate.DayOfWeek == DayOfWeek.Saturday || (IsSpecialDate(sDate) && !IsWork(sDate)))
                        {
                            aSb.AppendFormat("<td></td>");
                            pSb.AppendFormat("<td></td>");
                        }
                        else
                        {
                            //读取当天早上的请假记录
                            string aVacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 08:30:00"), "");

                            //读取当天早上的出差记录
                            string aEvection = GetEvection(et.Name, sDate);

                            if (aVacation == "" && aEvection == "")
                            {
                                aSb.AppendFormat("<td><font color='cc0000'>上午旷工</font></td>");
                            }
                            else if (aVacation != "")
                            {
                                aSb.AppendFormat("<td>{0}</td>", aVacation);
                            }
                            else if (aEvection != "")
                            {
                                aSb.AppendFormat("<td>{0}</td>", aEvection);
                            }

                            //读取当天下午的请假记录
                            string pVacation = GetVacation(et.Id, "", sDate.ToString("yyyy-MM-dd 17:30:00"));

                            //读取当天下午的出差记录
                            string pEvection = GetEvection(et.Name, sDate);

                            if (pVacation == "" && pEvection == "")
                            {
                                pSb.AppendFormat("<td><font color='cc0000'>下午旷工</font></td>");
                            }
                            else if (pVacation != "")
                            {
                                pSb.AppendFormat("<td>{0}</td>", pVacation);
                            }
                            else if (pEvection != "")
                            {
                                pSb.AppendFormat("<td>{0}</td>", pEvection);
                            }
                        }
                    }
                    sDate = sDate.AddDays(1);
                }
                aSb.Append("</tr>");
                pSb.Append("</tr>");
                fSb.Append(aSb);
                fSb.Append(pSb);
            }
            fSb.Append("</table>");
            return fSb.ToString();
        }

        public string FindByEmpId(int empId, DateTime startDate, DateTime endDate)
        {
            //按人员Id
            IEnumerable<empTemp> ets = ctx.ExecuteQuery<empTemp>("select JobNo,Name from Employee where Id={0}", empId.ToString());
            IEnumerable<cardLogTemp> cls = ctx.ExecuteQuery<cardLogTemp>(string.Format(@"select JobNo,CONVERT(varchar,CardTime,120) CardTime,Ip from CardLog where JobNo in(select JobNo from Employee
where Id={0}) and datediff(d,CardTime,'{1}')<=0 and datediff(d,CardTime,'{2}')>=0 order by CardTime", empId.ToString(), startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd")));

            IList<cardLogTemp> list = cls.ToList();
            empTemp et = ets.First();
            DateTime sDate = startDate;
            DateTime eDate = endDate;
            StringBuilder fSb = new StringBuilder();
            fSb.AppendFormat("<table class='s1'><caption>姓名:{0},月份:{1}</caption>", et.Name, sDate.ToString("yyyy年MM月"));
            fSb.Append("<thead><tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr></thead>");
            fSb.AppendFormat("<tr>");
            DateTime t = startDate;
            while (t.DayOfWeek != DayOfWeek.Sunday)
            {
                fSb.Append("<td></td>");
                t = t.AddDays(-1);
            }

            while (sDate <= eDate)//每天
            {
                if (sDate.DayOfWeek == DayOfWeek.Sunday)
                {
                    fSb.AppendFormat("</tr><tr>");
                }
                IEnumerable<cardLogTemp> clst = list.Where(r => r.JobNo == et.JobNo && r.CardTime.Substring(0, 10) == sDate.ToString("yyyy-MM-dd"));
                if (clst.Count() > 0)
                {
                    string aTime = clst.First().CardTime.Substring(11, 5);
                    if (int.Parse(aTime.Replace(":", "")) > 830)
                    {
                        //读取当天的请假记录
                        string vacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 08:30:00"), "");
                        //读取当天的出差记录
                        string evection = GetEvection(et.Name, sDate);
                        if (vacation == "" && evection == "")
                        {
                            if (int.Parse(aTime.Replace(":", "")) <= 900)
                            {
                                aTime = "<font color='cc0000'>" + aTime + "</font>";
                            }
                            else
                            {
                                aTime = "<font color='cc0000'>上午旷工</font>";
                            }
                        }
                        else if (vacation != "")
                            aTime = vacation;
                        else if (evection != "")
                            aTime = evection;
                    }
                    if (!string.IsNullOrEmpty(clst.First().Ip))
                    {
                        aTime += "<br /><span style='font-size:6pt;'>" + clst.First().Ip + "</span>";
                    }
                    string pTime = clst.Last().CardTime.Substring(11, 5);
                    if (int.Parse(pTime.Replace(":", "")) < 1730)
                    {
                        //读取当天的请假记录
                        string vacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 17:30:00"), "");
                        //读取当天的出差记录
                        string evection = GetEvection(et.Name, sDate);
                        if (vacation == "" && evection == "")
                        {
                            if (int.Parse(pTime.Replace(":", "")) >= 1700)
                            {
                                pTime = "<font color='cc0000'>" + pTime + "</font>";
                            }
                            else
                            {
                                pTime = "<font color='cc0000'>下午旷工</font>";
                            }
                        }
                        else if (vacation != "")
                            pTime = vacation;
                        else if (evection != "")
                            pTime = evection;
                    }
                    if (!string.IsNullOrEmpty(clst.Last().Ip))
                    {
                        pTime += "<br /><span style='font-size:6pt;'>" + clst.Last().Ip + "</span>";
                    }
                    fSb.Append("<td>");
                    fSb.AppendFormat("<div>{0}</div>", sDate.Day);
                    fSb.AppendFormat("<div>{0}</div>", aTime);
                    fSb.AppendFormat("<div>{0}</div>", pTime);
                    fSb.Append("</td>");
                }
                else//没有打卡记录
                {
                    if (sDate.DayOfWeek == DayOfWeek.Sunday || sDate.DayOfWeek == DayOfWeek.Saturday || (IsSpecialDate(sDate) && !IsWork(sDate)))
                    {
                        //不用上班
                        fSb.AppendFormat("<td><div>{0}</div></td>", sDate.Day);
                    }
                    else
                    {
                        string aTime = "";
                        //读取当天早上的请假记录
                        string aVacation = GetVacation(et.Id, sDate.ToString("yyyy-MM-dd 08:30:00"), "");

                        //读取当天早上的出差记录
                        string aEvection = GetEvection(et.Name, sDate);

                        if (aVacation == "" && aEvection == "")
                        {
                            aTime = "<font color='cc0000'>上午旷工</font>";
                        }
                        else if (aVacation != "")
                        {
                            aTime = aVacation;
                        }
                        else if (aEvection != "")
                        {
                            aTime = aEvection;
                        }

                        string pTime = "";
                        //读取当天下午的请假记录
                        string pVacation = GetVacation(et.Id, "", sDate.ToString("yyyy-MM-dd 17:30:00"));

                        //读取当天下午的出差记录
                        string pEvection = GetEvection(et.Name, sDate);

                        if (pVacation == "" && pEvection == "")
                        {
                            pTime = "<font color='cc0000'>下午旷工</font>";
                        }
                        else if (pVacation != "")
                        {
                            pTime = pVacation;
                        }
                        else if (pEvection != "")
                        {
                            pTime = pEvection;
                        }
                        fSb.Append("<td>");
                        fSb.AppendFormat("<div>{0}</div>", sDate.Day);
                        fSb.AppendFormat("<div>{0}</div>", aTime);
                        fSb.AppendFormat("<div>{0}</div>", pTime);
                        fSb.Append("</td>");
                    }
                }
                sDate = sDate.AddDays(1);
            }

            while (sDate.DayOfWeek != DayOfWeek.Sunday)
            {
                fSb.Append("<td></td>");
                sDate = sDate.AddDays(1);
            }
            fSb.Append("</tr>");
            fSb.Append("</table>");
            return fSb.ToString();
        }

        //在线打卡
        public ActionResult CardOnline()
        {
            EmpBasicInfo ebi = Session["ebi"] as EmpBasicInfo;
            var rdto = new ResultMessages();

            string jobNo = ctx.Employees.Single(r => r.Id == ebi.Id).JobNo;
            var obj = new CardLog();
            obj.JobNo = jobNo;
            obj.CardTime = DateTime.Now;
            obj.SysDate = DateTime.Now;
            obj.OperateId = ebi.Id;
            obj.Ip = Request.ServerVariables["REMOTE_ADDR"];
            ctx.CardLogs.InsertOnSubmit(obj);
            try
            {
                ctx.SubmitChanges();
                rdto.Result = true;
                rdto.Message = DateTime.Now.ToString("HH:mm:ss");
            }
            catch (Exception ex)
            {
                rdto.Result = false;
                rdto.Message = ex.Message;
            }

            return Json(rdto);
        }

        //根据员工ID跟日期 获取当天的请假记录情况
        private string GetVacation(int empid,string sDate,string eDate)
        {
            IEnumerable<string> vacationType;
            if(eDate=="")
            {
                vacationType = ctx.ExecuteQuery<string>(string.Format(@"SELECT a.VacationType+'|'+cast([StatusId] as nvarchar(50))FROM ReqVacationMains a,ReqVacationSubs b where a.FormNo=b.FormNo and a.EmpId={0} and '{1}' between PreStartTime and PreEndTime and a.StatusId!=0;", empid, sDate)).ToList();
            }
            else
            {
                vacationType = ctx.ExecuteQuery<string>(string.Format(@"SELECT a.VacationType+'|'+cast([StatusId] as nvarchar(50))FROM ReqVacationMains a,ReqVacationSubs b where a.FormNo=b.FormNo and a.EmpId={0} and ('{1}' between PreStartTime and PreEndTime or '{2}' between PreStartTime and PreEndTime) and a.StatusId!=0;", empid, sDate,eDate)).ToList();
                //vacationType = ctx.ExecuteQuery<string>(string.Format(@"SELECT a.VacationType+'|'+cast([StatusId] as nvarchar(50))FROM ReqVacationMains a,ReqVacationSubs b where a.FormNo=b.FormNo and a.EmpId={0} and '{1}' between PreStartTime and PreEndTime and a.StatusId!=0;", empid, eDate)).ToList();
            }
            string result = "";
            if (vacationType.Count() > 0)//有请假记录
            {
                if (vacationType.First().EndsWith("2"))
                {
                    result = "<font color='00cc00'>" + vacationType.First().Substring(0, 2) + "</font>";
                }
                else
                {
                    result = "<font color='fcd338'>" + vacationType.First().Substring(0, 2) + "审批未过</font>";
                }
            }
            return result;
        }

        //根据员工ID跟日期 获取当天的出差记录情况
        private string GetEvection(string name, DateTime sDate)
        {
            IEnumerable<string> evection = ctx.ExecuteQuery<string>(string.Format(@"SELECT cast([StatusId] as nvarchar(50))
  FROM ReqEvectionMains a,ReqEvectionSchedules b
  where a.TriperIds like '%{0}%' and a.FormNo=b.FormNo and '{1}' between PreStartTime and PreEndTime and a.StatusId!=0;", name, sDate.ToString("yyyy-MM-dd"))).ToList();
            string result = "";
            if (evection.Count() > 0)//有出差记录
            {
                if (evection.First().EndsWith("2"))
                {
                    result = "<font color='00cc00'>出差</font>";
                }
                else
                {
                    result = "<font color='fcd338'>出差审批未过</font>";
                }
            }
            return result;
        }

        private bool IsWork(DateTime date)
        {
            WorkOrRest wr = ctx.WorkOrRest.FirstOrDefault(q => q.SpecialDate.CompareTo(date) == 0);
            if (wr.IsWork == 0)
                return false;
            else
                return true;
        }

        private bool IsSpecialDate(DateTime date)
        {
            int count = ctx.WorkOrRest.Count(q => q.SpecialDate.CompareTo(date) == 0);
            if (count > 0)
                return true;
            else
                return false;
        }
    }
}